;
(function(window) {

  const clickoutside = {
    // 初始化指令
    bind(el, binding, vnode) {
      function documentHandler(e) {
        if (el.contains(e.target)) {
          return false;
        }
        if (binding.expression) {
          binding.value(e);
        }
      }

      el.__vueClickOutside__ = documentHandler;
      document.addEventListener('click', documentHandler);
    },
    unbind(el, binding) {
      document.removeEventListener('click', el.__vueClickOutside__);
      delete el.__vueClickOutside__;
    },
  };

  const hlAutocomplete = {
    template: `<div class="hl-autocomplete__container">
      <div class="hl-autocomplete__header"
          :style="{ 'width': selectWidth + 'px'}"
          :class="[
            type ? 'hl-autocomplete-' + type : '',
          ]"
          v-clickoutside="handleClose"
      >
        <input class="hl-autocomplete__input" type="text" autocomplete="off" :placeholder="placeholder" v-model="inputVal" @input="handleIptChange" @focus="handleIptChange">
      </div>

      <div
        class="hl-autocomplete-dropdown__container"
        :style="{ 'width': selectWidth + 'px' , 'max-height': selectDropdownHeight + 'px'}"
        v-if="dropdownIsShow"
      >
        <i  class="hl-autocomplete-dropdown__loading-icon"></i>
        <ul class="hl-autocomplete-dropdown__wrap">
          <li class="hl-autocomplete-dropdown__item" v-for="(item,index) in dropdownData" @click="selectItem(item,index)">{{item.name}}</li>
        </ul>
      </div>
    </div>`,
    data() {
      return {
        inputVal:'',
        dropdownData:[],
        dropdownIsShow:false,
      }
    },
    model: {
      prop: 'selected',
      event: 'on-select-item'
    },
    props:{
      data:{
        type:Array,
        default:() => []
      },
      selected:{
        type:[String,Object],
        default:''
      },
      width:{
        type:[String,Number],
        default:0
      },
      dropdownHeight:{
        type:[String,Number],
        default:200
      },
      size: {
        type:String,
        default:'medium'
      },
      type: {
        type:String,
        default:'primary'
      },
      placeholder: {
        type:String,
        default:'请输入'
      },
      autoMatch: {
        type:Boolean,
        default:true
      },
      fetchSuggestions: [Function],

    },
    directives: {
      clickoutside
    },
    computed:{
      selectWidth(){
        // 如果用户传入 width 值，则优先 width  其次参考 size
        if(this.width !== 0) return this.width

        if(this.size == 'samll') this.width = 126
        if(this.size == 'medium') this.width = 156
        if(this.size == 'large') this.width = 310

        return this.width
      },
      selectDropdownHeight(){
        return this.dropdownHeight
      },
    },
    watch:{
      data(val){
        this.dropdownData = val
      },
      selected(val){
        if( val && typeof val == 'string') this.inputVal = val
        if( val && typeof val == 'object') this.inputVal = val.name || ''
      }
    },
    created(){
      this.dropdownData = this.data

      if(this.selected && typeof this.selected == 'string') this.inputVal = this.selected
      if(this.selected && typeof this.selected == 'object') this.inputVal = this.selected.name || ''

    },
    methods:{
      handleIptChange(){
        const val = this.inputVal || ''

        if(this.selected == 'string') this.$emit('on-select-item',val)
        if(this.selected == 'object') this.$emit('on-select-item',{name:val,id:null})
        this.$emit('on-input',val)
        this.dropdownIsShow = true

        // 当传入 fetchSuggestions 时，采用远程获取数据，否则组件内部过滤数据
        if(this.fetchSuggestions && typeof this.fetchSuggestions === 'function'){
          this.dealRemoteData()
        }else{
          this.filterData()
        }
      },
      filterData(){
        const val = this.inputVal

        this.dropdownData = this.data.filter( el => el.name.indexOf(val) > -1 )
        if(this.autoMatch) this.matchDataByName()
      },
      dealRemoteData(){
        const val = this.inputVal

        this.fetchSuggestions(val,(data) => {
          this.dropdownData = data
          if(this.autoMatch) this.matchDataByName()
        })
      },
      // 根据输入的名称自动匹配对应的数据
      matchDataByName(){
        const val = this.inputVal

        for (let i = 0; i < this.dropdownData.length; i++) {
          let item = this.dropdownData[i]
          if(item.name == val){
            if(this.selected == 'string') this.$emit('on-select-item',val)
            if(this.selected == 'object') this.$emit('on-select-item',item)
            this.$emit('on-change',item,i)
            break
          }
        }
      },
      handleClose(){
        this.dropdownIsShow = false
        this.$emit('on-visible-change',false)
      },
      selectItem(item,i){
        this.inputVal = item.name
        this.dropdownIsShow = false

        if(this.selected && typeof this.selected == 'string') this.$emit('on-select-item',item.name)
        if(this.selected && typeof this.selected == 'object') this.$emit('on-select-item',item)

        this.$emit('on-change',item,i)
      }
    }

  }

  Vue.component('hl-autocomplete', hlAutocomplete)

}(window))
